import base64
import hmac
import hashlib
import json
from datetime import datetime
from time import mktime
from urllib.parse import urlencode
from wsgiref.handlers import format_date_time
import requests
from urllib.parse import urlparse

BASE_URL = "http://aiui.xf-yun.com/v2/aiint/voice-clone"

REG_PATH = "/sgen/reg"
DEL_PATH = "/sgen/del"

# a应用信息
APP_ID = ""
API_KEY = ""
API_SECRET = ""
# 设备sn号
SN = ""
# 需要复刻音频文件路径
FILE_PATH = ""

def assemble_auth_url(base_url, method="POST", api_key="", api_secret=""):
    host = urlparse(base_url).netloc
    path = urlparse(base_url).path
    # 生成RFC1123格式的时间戳
    now = datetime.now()
    date = format_date_time(mktime(now.timetuple()))

    # 拼接字符串
    signature_origin = "host: " + host + "\n"
    signature_origin += "date: " + date + "\n"
    signature_origin += method + " " + path + " HTTP/1.1"

    # 进行hmac-sha256进行加密
    print(signature_origin)
    signature_sha = hmac.new(api_secret.encode('utf-8'), signature_origin.encode('utf-8'), digestmod=hashlib.sha256).digest()
    signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')
    authorization_origin = f'api_key="{api_key}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'

    print('get authorization_origin:', authorization_origin)
    authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')

    # 将请求的鉴权参数组合为字典
    v = {
        "host": host,
        "date": date,
        "authorization": authorization,
    }
    # 拼接鉴权参数，生成url
    url = base_url + '?' + urlencode(v)
    print(url)
    # 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释，比对相同参数时生成的url与自己代码生成的url是否一致
    return url

# 上传文件进行声音复刻，拿到资源id
def sgenReg(appid, sn, audiopath, api_key, api_secret):
    form = {
        "appid": (None, appid),
        "sn": (None, sn),
        "data": open(audiopath, "rb"),
    }
    reqUrl = assemble_auth_url(base_url=BASE_URL + REG_PATH, method="POST", api_key=api_key, api_secret=api_secret)

    return requests.post(reqUrl, files=form).content.decode("utf8")

# 删除指定id的资源
def sgenDel(appid, sn, res_id, api_key, api_secret):
    reqUrl = assemble_auth_url(base_url=BASE_URL + DEL_PATH, method="DELETE", api_key=api_key, api_secret=api_secret)
    reqBody = {
        "appid": appid,
        "sn": sn,
        "res_id": res_id
    }

    return requests.delete(reqUrl, data=json.dumps(reqBody)).content.decode("utf8")

if __name__ == "__main__":
    # 声音复刻
    response_str = sgenReg(APP_ID, SN, FILE_PATH, API_KEY, API_SECRET)
    res = json.loads(response_str)
    if res["code"] != 0:
        print('sgenReg fail:', response_str)
        exit(-1)
    # 拿到资源id
    res_id = res["data"]["res_id"]
    print('voice clone success, sgenReg res_id:', res_id)

    # 复刻资源删除
    # res_id = "nlreosf1ire"
    # del_response_str = sgenDel(APP_ID, SN, res_id, API_KEY, API_SECRET)
    # del_res = json.loads(del_response_str)
    # if del_res["code"] != 0:
    #     print('sgenDel fail:', del_response_str)
    #     exit(-1)
    # print('voice clone res delete success')
